package com.smart.community.region.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.enums.SystemStatusEnum;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.region.dto.ShopOwnerDTO;
import com.smart.community.region.entity.ShopOwner;
import com.smart.community.region.entity.ShopOwnerRelation;
import com.smart.community.region.mapper.ShopOwnerMapper;
import com.smart.community.region.service.IShopOwnerRelationService;
import com.smart.community.region.service.IShopOwnerService;
import com.smart.community.region.vo.ShopOwnerRelationVO;
import com.smart.community.region.vo.ShopOwnerVO;

import cn.hutool.core.util.StrUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 店铺业主服务实现类
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-01-30
 */
@Slf4j
@Service
public class ShopOwnerServiceImpl extends ServiceImpl<ShopOwnerMapper, ShopOwner> implements IShopOwnerService {

    @Autowired
    private ShopOwnerMapper shopOwnerMapper;
    
    @Autowired
    private IShopOwnerRelationService shopOwnerRelationService;
    
    @Override
    @Cacheable(value = "shopOwner:page", key = "#page.current + '_' + #page.size + '_' + #ownerName + '_' + #ownerType + '_' + #ownerPhone + '_' + #ownerIdCard + '_' + #companyName + '_' + #email + '_' + #status + '_' + #keyword + '_' + #createTimeStart + '_' + #createTimeEnd")
    public IPage<ShopOwnerVO> getShopOwnerPage(Page<ShopOwner> page, String ownerName, Integer ownerType, String ownerPhone, 
            String ownerIdCard, String companyName, String email, Integer status, String keyword, 
            String createTimeStart, String createTimeEnd) {
        log.info("分页查询店铺业主列表，当前页：{}，每页大小：{}，业主姓名：{}，业主类型：{}，联系电话：{}，身份证号：{}，企业名称：{}，邮箱：{}，状态：{}，关键词：{}，创建开始时间：{}，创建结束时间：{}", 
                page.getCurrent(), page.getSize(), ownerName, ownerType, ownerPhone, ownerIdCard, companyName, email, status, keyword, createTimeStart, createTimeEnd);
        
        // 构建查询条件
        LambdaQueryWrapper<ShopOwner> queryWrapper = new LambdaQueryWrapper<>();
        
        // 基础条件
        queryWrapper.eq(ShopOwner::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
        
        // 业主姓名
        if (StrUtil.isNotBlank(ownerName)) {
            queryWrapper.like(ShopOwner::getOwnerName, ownerName);
        }
        
        // 业主类型
        if (ownerType != null) {
            queryWrapper.eq(ShopOwner::getOwnerType, ownerType);
        }
        
        // 联系电话
        if (StrUtil.isNotBlank(ownerPhone)) {
            queryWrapper.like(ShopOwner::getOwnerPhone, ownerPhone);
        }
        
        // 身份证号
        if (StrUtil.isNotBlank(ownerIdCard)) {
            queryWrapper.like(ShopOwner::getOwnerIdCard, ownerIdCard);
        }
        
        // 企业名称
        if (StrUtil.isNotBlank(companyName)) {
            queryWrapper.like(ShopOwner::getCompanyName, companyName);
        }
        
        // 邮箱
        if (StrUtil.isNotBlank(email)) {
            queryWrapper.like(ShopOwner::getEmail, email);
        }
        
        // 状态
        if (status != null) {
            queryWrapper.eq(ShopOwner::getStatus, status);
        }
        
        // 关键词搜索（搜索业主姓名、联系电话、企业名称、邮箱）
        if (StrUtil.isNotBlank(keyword)) {
            queryWrapper.and(wrapper -> wrapper
                .like(ShopOwner::getOwnerName, keyword)
                .or().like(ShopOwner::getOwnerPhone, keyword)
                .or().like(ShopOwner::getCompanyName, keyword)
                .or().like(ShopOwner::getEmail, keyword)
            );
        }
        
        // 创建时间范围
        if (StrUtil.isNotBlank(createTimeStart)) {
            queryWrapper.ge(ShopOwner::getCreateTime, createTimeStart + " 00:00:00");
        }
        if (StrUtil.isNotBlank(createTimeEnd)) {
            queryWrapper.le(ShopOwner::getCreateTime, createTimeEnd + " 23:59:59");
        }
        
        // 排序
        queryWrapper.orderByDesc(ShopOwner::getCreateTime);
        
        // 执行分页查询
        IPage<ShopOwner> shopOwnerPage = shopOwnerMapper.selectPage(page, queryWrapper);
        
        // 转换为VO
        IPage<ShopOwnerVO> result = shopOwnerPage.convert(shopOwner -> {
            ShopOwnerVO shopOwnerVO = new ShopOwnerVO();
            BeanUtils.copyProperties(shopOwner, shopOwnerVO);
            
            // 设置类型名称
            shopOwnerVO.setOwnerTypeName(getOwnerTypeName(shopOwner.getOwnerType()));
            
            // 设置状态名称
            shopOwnerVO.setStatusName(getStatusName(shopOwner.getStatus()));
            
            return shopOwnerVO;
        });
        
        log.info("分页查询店铺业主列表成功，总记录数：{}", result.getTotal());
        return result;
    }
    
    @Override
    @Cacheable(value = "shopOwner:detail", key = "#id")
    public ShopOwnerVO getShopOwnerById(Long id) {
        log.info("查询店铺业主详情，ID：{}", id);
        
        ShopOwner shopOwner = shopOwnerMapper.selectById(id);
        if (shopOwner == null) {
            log.warn("店铺业主不存在，ID：{}", id);
            return null;
        }
        
        ShopOwnerVO shopOwnerVO = new ShopOwnerVO();
        BeanUtils.copyProperties(shopOwner, shopOwnerVO);
        
        // 设置类型名称
        shopOwnerVO.setOwnerTypeName(getOwnerTypeName(shopOwner.getOwnerType()));
        
        // 设置状态名称
        shopOwnerVO.setStatusName(getStatusName(shopOwner.getStatus()));
        
        log.info("查询店铺业主详情成功，业主姓名：{}", shopOwnerVO.getOwnerName());
        return shopOwnerVO;
    }
    
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"shopOwner:page", "shopOwner:detail"}, allEntries = true)
    public Long createShopOwner(ShopOwnerDTO shopOwnerDTO) {
        log.info("创建店铺业主，业主姓名：{}", shopOwnerDTO.getOwnerName());
        
        // 1. 首先检查身份证号是否已存在（身份证号必填）
        LambdaQueryWrapper<ShopOwner> idCardQueryWrapper = new LambdaQueryWrapper<>();
        idCardQueryWrapper.eq(ShopOwner::getOwnerIdCard, shopOwnerDTO.getOwnerIdCard())
                         .eq(ShopOwner::getDeleted, 0);
        ShopOwner existingOwnerByIdCard = shopOwnerMapper.selectOne(idCardQueryWrapper);
        if (existingOwnerByIdCard != null) {
            throw new RuntimeException("身份证号在系统中已存在：" + shopOwnerDTO.getOwnerIdCard());
        }
        
        // 2. 然后检查手机号是否已存在
        LambdaQueryWrapper<ShopOwner> phoneQueryWrapper = new LambdaQueryWrapper<>();
        phoneQueryWrapper.eq(ShopOwner::getOwnerPhone, shopOwnerDTO.getOwnerPhone())
                        .eq(ShopOwner::getDeleted, 0);
        ShopOwner existingOwnerByPhone = shopOwnerMapper.selectOne(phoneQueryWrapper);
        if (existingOwnerByPhone != null) {
            throw new RuntimeException("手机号在系统中已存在：" + shopOwnerDTO.getOwnerPhone());
        }
        
        // 3. 创建业主实体
        ShopOwner shopOwner = new ShopOwner();
        BeanUtils.copyProperties(shopOwnerDTO, shopOwner);
        
        // 设置创建信息
        shopOwner.setCreateBy(SecurityUtils.getCurrentUserId());
        shopOwner.setDeleted(0);
        
        // 4. 保存业主
        int result = shopOwnerMapper.insert(shopOwner);
        if (result <= 0) {
            throw new RuntimeException("创建店铺业主失败");
        }
        
        // 5. 处理关联店铺关系
        if (shopOwnerDTO.getShopIds() != null && !shopOwnerDTO.getShopIds().isEmpty()) {
            createShopOwnerRelations(shopOwner.getId(), shopOwnerDTO.getShopIds());
        }
        
        log.info("创建店铺业主成功，业主ID：{}，业主姓名：{}", shopOwner.getId(), shopOwner.getOwnerName());
        return shopOwner.getId();
    }
    
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"shopOwner:page", "shopOwner:detail"}, allEntries = true)
    public boolean updateShopOwner(Long id, ShopOwnerDTO shopOwnerDTO) {
        log.info("更新店铺业主，ID：{}，业主姓名：{}", id, shopOwnerDTO.getOwnerName());
        
        // 检查业主是否存在
        ShopOwner existingOwner = shopOwnerMapper.selectById(id);
        if (existingOwner == null) {
            log.warn("店铺业主不存在，ID：{}", id);
            return false;
        }
        
        // 检查业主电话是否已被其他业主使用
        LambdaQueryWrapper<ShopOwner> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopOwner::getOwnerPhone, shopOwnerDTO.getOwnerPhone())
                   .ne(ShopOwner::getId, id)
                   .eq(ShopOwner::getDeleted, 0);
        ShopOwner existingOwnerByPhone = shopOwnerMapper.selectOne(queryWrapper);
        if (existingOwnerByPhone != null) {
            throw new RuntimeException("业主电话已被其他业主使用：" + shopOwnerDTO.getOwnerPhone());
        }
        
        // 检查身份证号是否已被其他业主使用（如果提供）
        if (shopOwnerDTO.getOwnerIdCard() != null && !shopOwnerDTO.getOwnerIdCard().trim().isEmpty()) {
            LambdaQueryWrapper<ShopOwner> idCardQueryWrapper = new LambdaQueryWrapper<>();
            idCardQueryWrapper.eq(ShopOwner::getOwnerIdCard, shopOwnerDTO.getOwnerIdCard())
                             .ne(ShopOwner::getId, id)
                             .eq(ShopOwner::getDeleted, 0);
            ShopOwner existingOwnerByIdCard = shopOwnerMapper.selectOne(idCardQueryWrapper);
            if (existingOwnerByIdCard != null) {
                throw new RuntimeException("身份证号已被其他业主使用：" + shopOwnerDTO.getOwnerIdCard());
            }
        }
        
        // 更新业主信息
        ShopOwner shopOwner = new ShopOwner();
        BeanUtils.copyProperties(shopOwnerDTO, shopOwner);
        shopOwner.setId(id);
        shopOwner.setUpdateBy(SecurityUtils.getCurrentUserId());
        
        int result = shopOwnerMapper.updateById(shopOwner);
        if (result <= 0) {
            throw new RuntimeException("更新店铺业主失败");
        }
        
        log.info("更新店铺业主成功，ID：{}，业主姓名：{}", id, shopOwnerDTO.getOwnerName());
        return true;
    }
    
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"shopOwner:page", "shopOwner:detail"}, allEntries = true)
    public boolean deleteShopOwner(Long id) {
        log.info("删除店铺业主，ID：{}", id);
        
        // 检查业主是否存在
        ShopOwner existingOwner = shopOwnerMapper.selectById(id);
        if (existingOwner == null) {
            log.warn("店铺业主不存在，ID：{}", id);
            return false;
        }
        
        // 逻辑删除
        LambdaUpdateWrapper<ShopOwner> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ShopOwner::getId, id)
                    .set(ShopOwner::getDeleted, 1)
                    .set(ShopOwner::getUpdateBy, SecurityUtils.getCurrentUserId());
        
        int result = shopOwnerMapper.update(null, updateWrapper);
        if (result <= 0) {
            throw new RuntimeException("删除店铺业主失败");
        }
        
        log.info("删除店铺业主成功，ID：{}", id);
        return true;
    }
    
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"shopOwner:page", "shopOwner:detail"}, allEntries = true)
    public boolean batchDeleteShopOwners(List<Long> ids) {
        log.info("批量删除店铺业主，IDs：{}", ids);
        
        if (ids == null || ids.isEmpty()) {
            log.warn("批量删除店铺业主失败，ID列表为空");
            return false;
        }
        
        // 批量逻辑删除
        LambdaUpdateWrapper<ShopOwner> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(ShopOwner::getId, ids)
                    .set(ShopOwner::getDeleted, 1)
                    .set(ShopOwner::getUpdateBy, SecurityUtils.getCurrentUserId());
        
        int result = shopOwnerMapper.update(null, updateWrapper);
        if (result <= 0) {
            throw new RuntimeException("批量删除店铺业主失败");
        }
        
        log.info("批量删除店铺业主成功，删除数量：{}", result);
        return true;
    }
    
    @Override
    @Cacheable(value = "shopOwner:shop", key = "#shopId")
    public List<ShopOwnerVO> getShopOwnersByShopId(Long shopId) {
        log.info("根据店铺ID查询业主列表，店铺ID：{}", shopId);
        
        // 这里需要通过关联表查询，暂时返回空列表
        // 实际实现需要关联查询sc_shop_owner_relation表
        log.info("根据店铺ID查询业主列表成功，店铺ID：{}，业主数量：0", shopId);
        return new ArrayList<>();
    }
    
    @Override
    @Cacheable(value = "shopOwner:owner", key = "#ownerId")
    public List<ShopOwnerVO> getShopsByOwnerId(Long ownerId) {
        log.info("根据业主ID查询关联店铺列表，业主ID：{}", ownerId);
        
        try {
            // 通过关联表查询店铺列表
            List<ShopOwnerRelationVO> relationList = shopOwnerRelationService.getShopsByOwnerId(ownerId);
            
            // 转换为ShopOwnerVO列表（只包含业主基本信息）
            List<ShopOwnerVO> shopList = new ArrayList<>();
            for (ShopOwnerRelationVO relation : relationList) {
                ShopOwnerVO shopOwnerVO = new ShopOwnerVO();
                // 只复制业主基本信息
                shopOwnerVO.setId(relation.getOwnerId());
                shopOwnerVO.setOwnerName(relation.getOwnerName());
                shopOwnerVO.setOwnerPhone(relation.getOwnerPhone());
                shopOwnerVO.setOwnerType(relation.getOwnerType());
                shopOwnerVO.setOwnerTypeName(relation.getOwnerTypeName());
                shopOwnerVO.setCompanyName(relation.getCompanyName());
                shopOwnerVO.setStatus(relation.getStatus());
                shopOwnerVO.setStatusName(relation.getStatusName());
                shopOwnerVO.setCreateTime(relation.getCreateTime());
                shopOwnerVO.setUpdateTime(relation.getUpdateTime());
                
                shopList.add(shopOwnerVO);
            }
            
            log.info("根据业主ID查询关联店铺列表成功，业主ID：{}，店铺数量：{}", ownerId, shopList.size());
            return shopList;
        } catch (Exception e) {
            log.error("根据业主ID查询关联店铺列表失败，业主ID：{}", ownerId, e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 创建店铺业主关联关系
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》的业务逻辑处理规范
     */
    private void createShopOwnerRelations(Long ownerId, List<Long> shopIds) {
        log.info("创建店铺业主关联关系，业主ID：{}，店铺IDs：{}", ownerId, shopIds);
        
        try {
            for (Long shopId : shopIds) {
                // 创建关联关系
                ShopOwnerRelation relation = new ShopOwnerRelation();
                relation.setOwnerId(ownerId);
                relation.setShopId(shopId);
                relation.setRelationType(1); // 默认业主关系
                relation.setIsPrimary(0); // 默认非主要联系人
                relation.setStatus(1); // 默认启用
                relation.setCreateBy(SecurityUtils.getCurrentUserId());
                
                // 保存关联关系
                shopOwnerRelationService.save(relation);
            }
            
            log.info("创建店铺业主关联关系成功，业主ID：{}，关联店铺数量：{}", ownerId, shopIds.size());
        } catch (Exception e) {
            log.error("创建店铺业主关联关系失败，业主ID：{}，店铺IDs：{}", ownerId, shopIds, e);
            throw new RuntimeException("创建店铺业主关联关系失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取业主类型名称
     */
    private String getOwnerTypeName(Integer ownerType) {
        if (ownerType == null) {
            return "未知";
        }
        switch (ownerType) {
            case 1:
                return "个人";
            case 2:
                return "企业";
            default:
                return "未知";
        }
    }
    
    /**
     * 获取状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 0:
                return "禁用";
            case 1:
                return "启用";
            default:
                return "未知";
        }
    }
}
